home *** CD-ROM | disk | FTP | other *** search
- // recvi3: (c) Günter Nagler 1996
- #include <stdio.h>
- #include <conio.h>
- #include <string.h>
- #include "sb.hpp"
- #include "korg.hpp"
- #include "filei3.hpp"
- #include <dir.h>
- #include "korgtext.hpp"
- #include <alloc.h>
-
- Soundcard* card = 0;
-
- char outputname[128], *outputext = 0;
- unsigned char data[32000];
- unsigned char *extra[4] = { 0, 0, 0, 0 };
- long len = 0;
- int working = 0;
- int recording = 0;
- int ignoring = 0;
-
- #define request_glb 0x0e
- #define send_glb 0x51
- #define request_dkt 0x0d
- #define send_dkt 0x52
- #define request_pcg 0x1c
- #define send_pcg 0x4c
- #define request_sty 0x31
- #define send_sty 0x65
- #define request_arr 0x30
- #define send_arr 0x64
- #define request_bsq 0x32
- #define send_bsq 0x66
- #define request_sng 0x18
- #define send_sng 0x48
- #define request_all 0x0f
- #define send_all 0x50
-
- // other korg sysex
- #define mode_change 0x4e
- #define param_change 0x41
- #define send_prog 0x40
- #define drumkit_change 0x53
-
- int request(Soundcard* card, int dumpmode)
- {
- if (!card)
- return 0;
- unsigned char req[6] = { 0xf0, 0x42, 0x30, 0x39, 0xFF, 0xf7 };
-
- req[4] = dumpmode;
- return card->play(req, sizeof(req)) == sizeof(req);
- }
-
- void record(unsigned char c)
- {
- if (len < sizeof(data))
- {
- data[(int)len] = c;
- len++;
- }
- else
- {
- int block = (int)((len / sizeof(data))-1);
- if (block >= 4)
- {
- len++;
- return;
- }
- int idx = (int)(len % sizeof(data));
- if (!extra[block])
- {
- if (idx == 0)
- {
- extra[block] = (unsigned char*)malloc(sizeof(data));
- if (!extra[block])
- {
- fprintf(stderr,"not enough memory to store dump\n");
- ignoring = 1;
- return;
- }
- }
- else
- return;
- }
- extra[block][idx] = c;
- len++;
- }
- }
-
- unsigned char* accessdata(long i, int* n)
- {
- if (i < sizeof(data))
- {
- if (len <= sizeof(data))
- *n = (int)(len-i);
- else
- *n = sizeof(data) - int(i);
- return data + int(i);
- }
- else if (i < len)
- {
- int block = int(i / sizeof(data))-1;
- int idx = (int)(i % sizeof(data));
- long nexti = ((i / sizeof(data))+1) * sizeof(data);
-
- if (len <= nexti)
- *n = (int)(len-i);
- else
- *n = sizeof(data) - idx;
- return extra[block] + idx;
- }
- *n = 0;
- return 0;
- }
-
- int setdata(unsigned char* s, int n, long i)
- {
- int maxn;
- int sum = 0;
-
- while (n > 0)
- {
- unsigned char* code = accessdata(i, &maxn);
- if (!code)
- return 0;
- if (maxn > n)
- maxn = n;
- memcpy(code, s, maxn);
- s += maxn;
- sum += maxn;
- n -= maxn;
- i += maxn;
- }
- return sum;
- }
-
- int getdata(unsigned char* s, int n, long i)
- {
- int maxn;
- int sum = 0;
-
- while (n > 0)
- {
- unsigned char* code = accessdata(i, &maxn);
- if (!code)
- return 0;
- if (maxn > n)
- maxn = n;
- memcpy(s, code, maxn);
- s += maxn;
- sum += maxn;
- n -= maxn;
- i += maxn;
- }
- return sum;
- }
-
- int getword(long i)
- {
- unsigned char v[2];
-
- getdata(v, 2, i);
-
- return v[0] + (int(v[1]) << 7);
- }
-
-
- int savedata(FILE* f, long i, long len)
- {
- if (!f || i < 0 || len <= 0)
- return 0;
- int n;
- while (len > 0)
- {
- unsigned char* code = accessdata(i, &n);
-
- if (n > len)
- n = (int)len;
- if (fwrite(code, n, 1, f) != 1)
- return 0;
- i += n;
- len -= n;
- }
- return 1;
- }
-
- long decodedata(long i, long count)
- {
- if (i < 0 || count <= 0 || i + count > len)
- return 0;
-
- unsigned char encoded[8];
- unsigned char decoded[7];
- long newi = i;
- long oldi = i;
- int enc, dec;
-
- while (count > 0)
- {
- if (count > 8)
- enc = 8;
- else
- enc = (int)count;
- getdata(encoded, enc, i);
- dec = code8to7(encoded, enc, decoded);
- setdata(decoded, dec, newi);
- newi += dec;
- count -= enc;
- i += enc;
- }
- /*
- count = len - i;
- while (count > 0)
- {
- if (count > 8)
- enc = 8;
- else
- enc = (int)count;
- getdata(encoded, enc, i);
- setdata(encoded, enc, newi);
- i+= enc;
- newi+=enc;
- count -= enc;
- }
- */
- return newi-oldi;
- }
-
- long saveglb(long pos = 5, int encoded = 1)
- {
- strcpy(outputext, "GLB");
- FILE* f = fopen(outputname, "wb");
- if (!f)
- {
- perror(outputname);
- return 0;
- }
-
- if (encoded)
- decodedata(pos, 32);
- if (savedata(f, pos, 28) <= 0)
- {
- fprintf(stderr, "error saving global data to %s\n", outputname);
- fclose(f);
- return 0;
- }
- fprintf(stderr, "saved global data to %s\n", outputname);
- fclose(f);
- return encoded ? 32 : 28;
- }
-
- long savedkt(long pos = 5, int encoded = 1)
- {
- strcpy(outputext, "DKT");
- FILE* f = fopen(outputname, "wb");
- if (!f)
- {
- perror(outputname);
- return 0;
- }
-
- if (encoded)
- decodedata(5, 960);
- if (savedata(f, pos, 840) <= 0)
- {
- fprintf(stderr, "error saving drumkit data to %s\n", outputname);
- fclose(f);
- return 0;
- }
- fprintf(stderr, "saved drumkit data to %s\n", outputname);
- fclose(f);
- return encoded ? 960 : 840;
- }
-
- long savepcg(long pos = 5, int encoded = 1)
- {
- PCGHEAD head;
-
- memset(&head, 0, sizeof(head));
- memcpy(head.korg, "KORG", 4);
- head.unknown[0] = '9';
-
-
- strcpy(outputext, "PCG");
- FILE* f = fopen(outputname, "wb");
- if (!f)
- {
- perror(outputname);
- return 0;
- }
-
- if (encoded)
- decodedata(pos, 12371);
-
- long ofs = 0x58;
-
- head.b1.adr = ofs; ofs += (head.b1.len = 0);
- head.prognames.adr = ofs; ofs += (head.prognames.len = 10*66);
- head.globals.adr = ofs; ofs += (head.globals.len = 0);
- head.drumkits.adr = ofs; ofs += (head.drumkits.len = 0);
- head.b5.adr = ofs; ofs += (head.b5.len = 0);
- head.progdata.adr = ofs; ofs += (head.progdata.len = 164 * 66);
- head.b7.adr = ofs; ofs += (head.b7.len = 0);
- head.b8.adr = ofs; ofs += (head.b8.len = 0);
- head.b9.adr = ofs; ofs += (head.b9.len = 0);
-
- if (fwrite(&head, sizeof(head), 1,f) != 1)
- return 0;
-
- // program names
- for (long i = pos, j = 0; j < 66; j++, i+= 164)
- {
- if (!savedata(f, i, 10))
- return 0;
- }
-
- if (savedata(f, pos, 164*66) <= 0)
- {
- fprintf(stderr, "error saving program data to %s\n", outputname);
- fclose(f);
- return 0;
- }
- fprintf(stderr, "saved program data to %s\n", outputname);
- fclose(f);
- return encoded ? 12371 : 66*164;
- }
-
- long savesty(long pos = 5, int encoded = 1)
- {
- STYHEAD head;
-
- memset(&head, 0, sizeof(head));
- memcpy(head.korg, "KORG", 4);
- head.unknown[0] = '9';
- head.unknown[2] = 4;
- head.stylenames.adr = 0x20;
- head.stylenames.len = 10 * 4;
- head.styletable.adr = 0x48;
- head.styletable.len = sizeof(STYLINK) * 4;
-
- strcpy(outputext, "STY");
- FILE* f = fopen(outputname, "wb");
- if (!f)
- {
- perror(outputname);
- return 0;
- }
- STYLINK style[4];
-
- if (encoded)
- {
- unsigned char buf[28];
- getdata(buf, 28, pos);
- int n = 28;
- unsigned char* b = buf;
- unsigned char* s = (unsigned char*)&style;
- while (n > 0)
- {
- code8to7(b, n, s);
- n -= 8;
- b += 8;
- s += 7;
- }
- }
- else
- getdata((unsigned char*)style, sizeof(style), pos);
-
- long decsize = long(style[0].len) + long(style[1].len) +
- long(style[2].len) + long(style[3].len) + 24;
- long encsize = (decsize / 7) * 8 + (decsize % 7) + 1;
- if (encoded)
- decodedata(pos, encsize);
-
- if (fwrite(&head, 0x20, 1,f) != 1)
- return 0;
-
- int j = 0;
- for (long i = pos, k = pos+4*6; j < 4; j++, i+= 6)
- {
- if (!savedata(f, k, 10))
- return 0;
- k += style[j].len;
- }
-
- if (savedata(f, pos, decsize) <= 0)
- {
- fprintf(stderr, "error saving style data to %s\n", outputname);
- fclose(f);
- return 0;
- }
- fprintf(stderr, "saved style data to %s\n", outputname);
- fclose(f);
- return encoded ? encsize : decsize;
- }
-
- long savearr(long pos = 5, int encoded = 1)
- {
- ARRHEAD head;
-
- memset(&head, 0, sizeof(head));
- memcpy(head.korg, "KORG", 4);
- head.unknown[0] = '9';
- head.unknown[2] = 3;
- head.arrnames.adr = 0x20;
- head.arrnames.len = 10 * 64;
- head.arrdata.adr = 0x2a0;
- head.arrdata.len = 64 * 131;
-
- strcpy(outputext, "ARR");
- FILE* f = fopen(outputname, "wb");
- if (!f)
- {
- perror(outputname);
- return 0;
- }
-
- if (encoded)
- decodedata(pos, 9582);
-
- if (fwrite(&head, 0x20, 1,f) != 1)
- return 0;
-
- for (long i = pos, j = 0; j < 64; j++, i+= 131)
- {
- if (!savedata(f, i, 10))
- return 0;
- }
-
- if (savedata(f, pos, 131*64) <= 0)
- {
- fprintf(stderr, "error saving arrangement data to %s\n", outputname);
- fclose(f);
- return 0;
- }
- fprintf(stderr, "saved arrangement data to %s\n", outputname);
- fclose(f);
- return encoded ? 9582 : 131*64;
- }
-
- long savebsq(long pos = 7, unsigned steps = 0, int encoded = 1)
- {
- BSQHEAD head;
-
- memset(&head, 0, sizeof(head));
- memcpy(head.korg, "KORG", 4);
- head.unknown[0] = '9';
- head.unknown[2] = 1;
- head.unknown[3] = 1;
-
- strcpy(outputext, "BSQ");
- FILE* f = fopen(outputname, "wb");
- if (!f)
- {
- perror(outputname);
- return 0;
- }
-
- long decsize = 2292 + 16l * steps;
- long encsize = (decsize / 7) * 8 + (decsize % 7) + 1;
-
- if (encoded)
- decodedata(pos, encsize);
-
- for (long i = pos+0x79e, j = 0; j < 171; j++, i+=2)
- {
- unsigned v;
-
- getdata((unsigned char*)&v, 2, i);
- v += 15; // don't know why
- setdata((unsigned char*)&v, 2, i);
- }
-
- if (fwrite(&head, 0x10, 1,f) != 1)
- return 0;
-
- if (savedata(f, pos, decsize) <= 0)
- {
- fprintf(stderr, "error saving backing sequence data to %s\n", outputname);
- fclose(f);
- return 0;
- }
- fprintf(stderr, "saved backing sequence data to %s\n", outputname);
- fclose(f);
- return encoded ? encsize : decsize;
- }
-
- long savesng(long pos = 7, unsigned steps = 0, int encoded = 1)
- {
- SNGHEAD head;
-
- memset(&head, 0, sizeof(head));
- memcpy(head.korg, "KORG", 4);
- head.unknown[0] = '9';
- head.unknown[1] = 1;
- head.unknown[2] = 1;
-
- strcpy(outputext, "SNG");
- FILE* f = fopen(outputname, "wb");
- if (!f)
- {
- perror(outputname);
- return 0;
- }
-
- long decsize = 3702 + 16l * steps;
- long encsize = (decsize / 7) * 8 + (decsize % 7) + 1;
-
- if (encoded)
- decodedata(pos, encsize);
-
- for (long i = pos + 0xc58, j = 0; j < 271; j++, i+=2)
- {
- unsigned v;
-
- getdata((unsigned char*)&v, 2, i);
- v += 15; // don't know why
- setdata((unsigned char*)&v, 2, i);
- }
-
- if (fwrite(&head, 0x10, 1,f) != 1)
- return 0;
-
- if (savedata(f, pos, decsize) <= 0)
- {
- fprintf(stderr, "error saving song data to %s\n", outputname);
- fclose(f);
- return 0;
- }
- fprintf(stderr, "saved song data to %s\n", outputname);
- fclose(f);
- return encoded ? encsize : decsize;
- }
-
- long saveall(long pos = 5)
- {
- long oldpos = pos;
-
- unsigned bseqsteps, songsteps;
-
- songsteps = getword(pos); pos += 2;
- bseqsteps = getword(pos); pos += 2;
-
- long declen= decodedata(pos, len-pos-1);
-
- pos += saveglb(pos, 0);
- pos += savedkt(pos, 0);
- pos += savepcg(pos, 0);
- pos += savearr(pos, 0);
- pos += savesty(pos, 0);
- pos += savesng(pos, songsteps, 0);
- pos += savebsq(pos, bseqsteps, 0);
- return pos-oldpos;
- }
-
- void saverecording()
- {
- unsigned steps = 0;
-
- switch(data[4])
- {
- case send_glb:
- saveglb();
- break;
- case send_dkt:
- savedkt();
- break;
- case send_pcg:
- savepcg();
- break;
- case send_sty:
- savesty();
- break;
- case send_arr:
- savearr();
- break;
- case send_bsq:
- steps = getword(5);
- savebsq(7, steps);
- break;
- case send_sng:
- steps = getword(5);
- savesng(7, steps);
- break;
- case send_all:
- saveall();
- break;
- }
- }
-
- void unknownsysex()
- {
- if (data[1] == 0x7e && data[3] == 6 && data[4] == 2)
- {
- printf("identification: ");
- for (int i = 0; i < len; i++)
- printf(" %02X", data[i]);
- printf("\n");
- printf("Manufacturer id: %02X", data[5]);
- int known = 0;
-
- switch(data[5])
- {
- case 1: printf(" Sequential Circuits"); break;
- case 2: printf(" Big Briar"); break;
- case 3: printf(" Octave / Plateau"); break;
- case 4: printf(" Moog"); break;
- case 5: printf(" Passport Designs"); break;
- case 6: printf(" Lexicon"); break;
- case 0x11: printf(" PAIA"); break;
- case 0x12: printf(" Simmons"); break;
- case 0x13: printf(" Gentle Electric"); break;
- case 0x14: printf(" Fairlight"); break;
- case 0x20: printf(" Bontempi"); break;
- case 0x21: printf(" S.I.E.L"); break;
- case 0x23: printf(" SyntheAxe"); break;
- case 0x40: printf(" Kawai"); break;
- case 0x41: printf(" Roland"); break;
- case 0x42: printf(" Korg"); known = 1; break;
- case 0x43: printf(" Yamaha"); break;
- }
- printf("\n");
- int v = getword(6);
- printf("Family code: %02Xh ", v);
- if (known && v == 0x39)
- printf(" i2/i3");
- else
- known = 0;
- printf("\n");
- v = getword(8);
- printf("Member code: %02Xh ", v);
- if (known && v == 0)
- printf(" i3");
- else if (known && v == 1)
- printf(" i2");
- else
- known = 0;
- printf("\n");
- v = getword(8);
- printf("ROM No: %02Xh (%d)\n", v, v);
- v = getword(10);
- printf("Software Version: %02Xh (%d)\n", v, v);
- }
- else
- {
- printf("unknown system exclusive message ");
- for (int i = 0; i < 5; i++)
- printf(" %02X", data[i]);
- printf(" ... F7\n");
- }
- }
-
- int receivedump(int what = -1)
- {
- static unsigned char hearbuf[1024];
- int hearlen;
- unsigned char c;
- int v;
- unsigned steps;
-
-
- card->startinput();
- while (!kbhit() || getch() != 27)
- {
- if ((hearlen = card->hear(hearbuf, sizeof(hearbuf))) <= 0)
- continue;
- working = 1;
- for (int i = 0; i < hearlen; i++)
- {
- c = hearbuf[i];
- if (c == 0xf8 || c == 0xfe)
- continue;
- if (!recording)
- {
- if (c == 0xf0)
- {
- recording = 1;
- ignoring = 0;
- len = 0;
- record(c);
- }
- continue;
- }
- // recording
- if (len % 1000 == 0)
- fprintf(stderr, "%ld\r", len);
-
- if (len == 100)
- {
- if (data[1] != 0x42 || data[2] != 0x30 || data[3] != 0x39)
- ignoring = 1; // unknown sysex
- else if (what >= 0 && data[4] != what)
- ignoring = 1;
- }
- if (!ignoring)
- {
- record(c);
- }
- if (c == 0xf7)
- {
- printf("%ld bytes received: ", len);
- recording = 0;
-
- if (data[1] != 0x42 || data[2] != 0x30)
- {
- unknownsysex();
- if (data[1] == 0x7e && data[3] == 6 && data[4] == 2)
- ungetch(27);
- }
- else
- {
- switch(data[4])
- {
- case send_glb:
- printf("global data dump\n");
- break;
- case send_dkt:
- printf("drumkit data dump\n");
- break;
- case send_pcg:
- printf("all program data dump\n");
- break;
- case send_sty:
- printf("all style data dump\n");
- break;
- case send_arr:
- printf("all arrangement data dump\n");
- break;
- case send_bsq:
- steps = data[5] + (data[6] << 7);
- printf("all backing sequence data dump (%d steps)\n", steps);
- break;
- case send_sng:
- steps = data[5] + (data[6] << 7);
- printf("all song data dump (%d steps)\n", steps);
- break;
- case send_all:
- printf("all data dump\n");
- break;
- case mode_change:
- printf("mode changed to %s\n", kbdmode(data[5]));
- break;
- case param_change:
- v = (int(data[9]) << 7) + data[8];
- if (v & 0x2000)
- v = v-0x4000;
- printf("parameter changed in Page %d Stage %d Position %d to Value %d\n",
- data[5], data[6], data[7], v);
- break;
- case send_prog:
- unsigned char name[14];
- code8to7(data+5, 8, name);
- code8to7(data+5+8, 8, name+7);
- printf("program data dump %-10.10s\n", name);
- break;
-
- case drumkit_change:
- v = (int(data[9]) << 7) + data[8];
- if (v & 0x2000)
- v = v-0x4000;
- printf("drumkit parameter changed in Dr%d Param %d to Value %d\n",
- data[5]+1, data[6], v);
- break;
- default:
- unknownsysex();
- break;
- }
- }
-
- if (!ignoring)
- {
- saverecording();
- if (what >= 0 && data[4] == what) // finished automatically
- {
- hearlen = 0;
- ungetch(27);
- break;
- }
- }
- }
- }
- }
- card->stopinput();
- return working != 0;
- }
-
- void checkresponse()
- {
- #define RETRY 1000
-
- card->startinput();
-
- for (long i = 0; i < RETRY; i++)
- if (card->hear(data, 1))
- break;
- if (i == RETRY)
- fprintf(stderr, "Warning: no response from KORG. Transfer might not work.\n");
- else
- fprintf(stderr, "KORG responded\n");
-
- card->stopinput();
- }
-
- int main(int argc, char** argv)
- {
- int requestid = -1;
- int sendid = -1;
- int identify = 0;
-
- argc--; argv++;
- while (argc > 0 && **argv == '-')
- {
- if (strnicmp(*argv, "-h", 2) == 0 || strcmp(*argv ,"-?") == 0)
- {
- printf("usage: recvi3 [-identify] [filename]\n");
- printf("-identify\trequest identification of KORG i3 keyboard\n");
- printf("filename\tshould have extension *,PCG,STY,ARR,SNG,BSQ,GLB,DKT\n");
- printf("When no filename specified then dump must be sent manually\n");
- return 1;
- }
- if (strnicmp(*argv, "-identify", 2) == 0)
- {
- identify = 1;
- argc--; argv++; continue;
- }
- fprintf(stderr, "invalid option %s\n", *argv);
- argc--; argv++;
- }
- if (argc > 0)
- {
- strcpy(outputname, *argv++); argc--;
- char* ext = strrchr(outputname, '.');
- if (ext)
- {
- ext++;
- if (stricmp(ext, "glb") == 0)
- {
- requestid = request_glb;
- sendid = send_glb;
- }
- else if (stricmp(ext, "dkt") == 0)
- {
- requestid = request_dkt;
- sendid = send_dkt;
- }
- else if (stricmp(ext, "pcg") == 0)
- {
- requestid = request_pcg;
- sendid = send_pcg;
- }
- else if (stricmp(ext, "sty") == 0)
- {
- requestid = request_sty;
- sendid = send_sty;
- }
- else if (stricmp(ext, "arr") == 0)
- {
- requestid = request_arr;
- sendid = send_arr;
- }
- else if (stricmp(ext, "bsq") == 0)
- {
- requestid = request_bsq;
- sendid = send_bsq;
- }
- else if (stricmp(ext, "sng") == 0)
- {
- requestid = request_sng;
- sendid = send_sng;
- }
- else if (stricmp(ext, "*") == 0)
- {
- requestid = request_all;
- sendid = send_all;
- }
- else
- fprintf(stderr, "unknown korg extenxion %s ignored\n", ext);
- *ext = 0;
- }
- else
- strcat(outputname, ".");
- }
- else
- strcpy(outputname, "KORGI3.");
- outputext = outputname + strlen(outputname);
- strupr(outputname);
- card = detect_soundcard();
- if (!card)
- {
- fprintf(stderr, "Could not detect soundcard\n");
- return 1;
- }
-
- checkresponse();
-
- if (identify)
- {
- card->play("\xf0\x7e\x00\x06\x01\xf7", 6);
- fprintf(stderr, "requesting identification\n");
- requestid = -1;
- sendid = -1;
- }
- else if (requestid >= 0)
- fprintf(stderr, "requesting dump from korg\n");
- else
- fprintf(stderr, "waiting for receiving korg dumps. press <esc> to abort\n");
- if (requestid >= 0 && !request(card, requestid))
- {
- fprintf(stderr, "requesting dump failed. start dump manually\n");
- }
-
- int ret = receivedump(sendid);
-
- delete card;
- return ret;
- }
-